import base64
import json
import os
import shutil

import toml
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC

from common import get_app_support_directory

# 使用固定的盐值，这样每次生成的密钥都是一样的
SALT = b"subtitle_agent_salt"
# 使用固定的密码
PASSWORD = b"subtitle_agent_password"


def get_config_path():
    config_dir = get_app_support_directory()
    config_path = os.path.join(config_dir, "config.toml")
    return config_path


def get_encryption_key():
    """生成加密密钥"""
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=SALT,
        iterations=480000,
    )
    key = base64.urlsafe_b64encode(kdf.derive(PASSWORD))
    return key


class AppConfig:
    """应用配置"""

    def __new__(cls):
        if not hasattr(cls, "instance"):
            cls.instance = super(AppConfig, cls).__new__(cls)
        return cls.instance

    def __init__(self):
        self.conf_keys = ["api_key", "groq_api_key", "base_url", "model"]
        self.config = {}
        self.fernet = Fernet(get_encryption_key())
        self.load_config()

    def load_config(self):
        """加载配置文件"""
        try:
            if not os.path.exists(get_config_path()) and os.path.exists("config.toml"):
                shutil.copy("config.toml", get_config_path())

            with open(get_config_path(), "r", encoding="utf-8") as f:
                config = toml.load(f)

            self.config = {}
            # 检查是否是加密数据
            if "encrypted_data" in config:
                # 解密数据
                try:
                    encrypted_data = config["encrypted_data"].encode()
                    decrypted_data = self.fernet.decrypt(encrypted_data)
                    config = json.loads(decrypted_data)
                    for key in self.conf_keys:
                        if key in config:
                            self.config[key] = config[key]
                        else:
                            self.config[key] = ""
                    self.config["multi_config"] = config.get("multi_config", {})
                except Exception as e:
                    print(f"解密失败: {str(e)}")
                    # 如果解密失败，使用空值
                    for key in self.conf_keys:
                        self.config[key] = ""
            else:
                # 未加密的旧配置文件
                for key in self.conf_keys:
                    if key in config:
                        self.config[key] = config[key]
                    else:
                        self.config[key] = ""
                self.config["multi_config"] = config.get("multi_config", {})
        except FileNotFoundError:
            # 文件不存在时使用空值
            for key in self.conf_keys:
                self.config[key] = ""

    def save_config(self):
        """保存配置文件"""
        try:
            # 将配置数据转换为JSON字符串
            config_json = json.dumps(self.config)
            # 加密数据
            encrypted_data = self.fernet.encrypt(config_json.encode())
            # 保存加密后的数据
            config_to_save = {"encrypted_data": encrypted_data.decode()}
            with open(get_config_path(), "w", encoding="utf-8") as f:
                toml.dump(config_to_save, f)
        except Exception as e:
            print(f"保存配置失败: {str(e)}")
            raise

    def __getitem__(self, key):
        """获取配置项"""
        if key == "multi_config_keys":
            multi_config = self.config.get("multi_config", {})
            keys = list(multi_config.keys())
            return keys
            
        return self.config[key]

    def __setitem__(self, key, value):
        """设置配置项"""
        if key not in self.conf_keys:
            raise KeyError(f"Invalid key: {key}")
        self.config[key] = value
        self.save_config()

    def save_multi_config(self, name):
        """保存多配置文件"""
        multi_config = self.config.setdefault("multi_config", {})
        multi_config[name] = {}
        for key in self.conf_keys:
            multi_config[name][key] = self.config.get(key, "")
        self.save_config()

    def load_multi_config(self, name):
        """加载多配置文件"""
        multi_config = self.config.get("multi_config", {})
        if name in multi_config:
            for key in self.conf_keys:
                self.config[key] = multi_config[name].get(key, "")
            self.save_config()
            print(f"加载配置文件 {name} 成功:{self.config}")
            return True
        return False

    def del_multi_config(self, name):
        """删除多配置文件"""
        multi_config = self.config.get("multi_config", {})
        if name in multi_config:
            del multi_config[name]
            self.save_config()
            return True
        return False